package demo02

import (
	"fmt"
	"time"
)

// https://juejin.cn/post/7418391732163969039
// select的使用

/*
SelectDemo1
执行到select语句的时候，由于ch中没有数据，且没有goroutine往channel中写数据，所以不可能执行到，就会执行default语句，打印出default!!!
3.3 有单一case和default的select
*/
func SelectDemo1() {
	ch := make(chan int)
	//go func() {
	//	ch <- 1
	//}()
	//time.Sleep(time.Second)
	select {
	case <-ch:
		fmt.Println("received from ch")
	default:
		fmt.Println("default!!!")
	}
}

/*
SelectDemo2
3.4 有多个case和default的select
主goroutine中向后往管道ch1和ch2中发送数据，在子goroutine中执行两个select，可以看到，在执行select的时候，那个case准备好了就会执行当下case的语句，
最后没有数据可接受了，没有case可以执行，则执行default语句。
这里注意：当多个case都准备好了的时候，会随机选择一个执行
*/
func SelectDemo2() {
	ch1 := make(chan int, 1)
	ch2 := make(chan int, 1)
	go func() {
		time.Sleep(time.Second)
		for i := 0; i < 3; i++ {
			select {
			case v := <-ch1:
				fmt.Printf("Received from ch1, val = %d\n", v)
			case v := <-ch2:
				fmt.Printf("Received from ch2, val = %d\n", v)
			default:
				fmt.Println("default!!!")
			}
			time.Sleep(time.Second)
		}
	}()
	ch1 <- 1
	time.Sleep(time.Second)
	ch2 <- 2
	time.Sleep(time.Second)
}

// SelectDemo3 多次执行，2个case都有可能打印，这就是select选择的随机性
func SelectDemo3() {
	ch1 := make(chan int, 1)
	ch2 := make(chan int, 1)
	ch1 <- 1
	ch2 <- 2
	select {
	case v := <-ch1:
		fmt.Printf("Received from ch1, val = %d\n", v)
	case v := <-ch2:
		fmt.Printf("Received from ch2, val = %d\n", v)
	default:
		fmt.Println("default!!!")
	}
}
